﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure.ServiceRuntime;
using System.IO;
using DBFile.Core.Interfaces;

namespace DBFile.AzureLocalStorageProvider.Impl
{
    public class LocalStorageClient: IDBFileProvider
    {
        private const int Success = 1;
        private const int Fail = 0;

        private string storageName;
        
        public LocalStorageClient(string storageName)
        {
            this.storageName = storageName;
        }

        public bool Exists(string filename)
        {
            return File.Exists(GetFilePath(filename));
        }

        public int Copy(string sourceFilename, string destinationFilename, bool overwrite)
        {
            try
            {
                File.Copy(GetFilePath(sourceFilename), GetFilePath(destinationFilename), overwrite);
            }
            catch
            {
                return Fail;
            }
            return Success;
        }

        public int Insert(string filename, byte[] buffer, string contentType, long contentLength)
        {
            try
            {
                File.WriteAllBytes(GetFilePath(filename), buffer);
            }
            catch
            {
                return Fail;
            }
            return Success;
        }

        public int Insert(string filename, byte[] buffer, string contentType, long contentLength, bool overwrite)
        {
            try
            {
                if (!overwrite && File.Exists(GetFilePath(filename)))
                {
                    return Fail;
                }
                else
                {
                    File.WriteAllBytes(GetFilePath(filename), buffer);
                }
            }
            catch
            {
                return Fail;
            }
            return Success;
        }

        public int Update(string filename, byte[] buffer, string contentType, long contentLength)
        {
            try
            {
                File.WriteAllBytes(GetFilePath(filename), buffer);
            }
            catch
            {
                return Fail;
            }
            return Success;
        }

        public int Delete(string filename)
        {
            try
            {
                if (File.Exists(GetFilePath(filename)))
                {
                    File.Delete(GetFilePath(filename));
                }
                else
                {
                    return Fail;
                }
            }
            catch
            {
                return Fail;
            }
            return Success;
        }

        public string[] GetFileNameList()
        {
            return (from fileName in Directory.GetFiles(GetLocalStore(storageName))
                    select Path.GetFileName(GetFilePath(fileName))).ToArray();
        }

        public T Get<T>(string filename) where T : IDBFile, new()
        {
            T file = new T();

            FileStream fs = File.Open(GetFilePath(filename), FileMode.Open, FileAccess.Read, FileShare.Read);
            try
            {
                file.FileName = filename;
                file.ContentLength = fs.Length;
                file.ContentType = DBFile.Core.DBFile.GetContentType(Path.GetExtension(filename));

                file.FileBytes = new byte[fs.Length];
                fs.Read(file.FileBytes, 0, (int)fs.Length);

            }
            finally
            {
                fs.Close();
            }
            return file;
        }

        public string GetFilePath(string filename)
        {
            return Path.Combine(GetLocalStore(storageName), filename);
        }

        private static string GetLocalStore(string storageName)
        {
            if (RoleEnvironment.IsAvailable)
            {
                return RoleEnvironment.GetLocalResource(storageName).RootPath;
            }
            else
            {
                string localStores = Path.Combine(Path.Combine(Path.GetTempPath(), "localstores"), Path.GetRandomFileName());

                string dirPath = Path.Combine(localStores, storageName);
                Directory.CreateDirectory(dirPath);

                return dirPath;
            }
        }
    }
}
